/******************************************************************************
Filename    : bincopy.c
Author      : pry
Date        : 24/06/2017
Description : The binary to array translator. This is used to generate an array
              containing the binary of the image so it can be used by the C compiler.
******************************************************************************/

/* Includes ******************************************************************/
#include "time.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
/* End Includes **************************************************************/

/* Defines *******************************************************************/
/* Failure reporting macros */
#define BINCOPY_FAIL(Reason) \
{ \
	printf("Error:"); \
	printf(Reason); \
	printf("\n\n"); \
	if(Input_File!=0) \
		fclose(Input_File); \
	if(Output_File!=0) \
		fclose(Output_File); \
	exit(-1); \
}
/* End Defines ***************************************************************/

/* Typedefs ******************************************************************/
typedef char s8;
typedef short s16;
typedef int s32;
typedef long long s64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef s32 ret_t;
typedef s32 cnt_t;
/* End Typedefs **************************************************************/

/* Global Variables **********************************************************/
FILE* Input_File=0;
FILE* Output_File=0;
s8* Output_Name=0;
s8 Section_Name[8192];
cnt_t Input_Size;
/* End Global Variables ******************************************************/

/* Begin Function:main ********************************************************
Description : The main function.
Input       : int argc - The number of input arguments.
              char* argv[] - The arguments.
Output      : None.
Return      : int - Return value.
******************************************************************************/
int main(int argc, char* argv[])
{
	cnt_t Count;
	time_t Raw_Time;
    u8 Temp;
    cnt_t Name_Start;

	time(&Raw_Time);

	if(argc!=5)
		BINCOPY_FAIL("Too many or too few input parameters.\n"
				     "Usage: -i input.bin -o output.c.\n"
                     "       -i: Input file name and path, with extension.\n"
                     "       -o: Output file name and path, with extension.\n");

	Count=1;
	/* Read the command line one by one */
	while(Count<argc)
	{
		/* We need to open some input file */
		if(strcmp(argv[Count],"-i")==0)
		{
			if(Input_File!=0)
				BINCOPY_FAIL("More than one input file.");

			Input_File=fopen(argv[Count+1],"rb");
			if(Input_File==0)
				BINCOPY_FAIL("Input file open failure.");

			Count+=2;
		}
		/* We need to open some output file */
		else if(strcmp(argv[Count],"-o")==0)
		{
			if(Output_File!=0)
				BINCOPY_FAIL("More than one output file.");

			Output_File=fopen(argv[Count+1],"w");
			Output_Name=argv[Count+1];
			if(Output_File==0)
				BINCOPY_FAIL("Output file open failure.");

			Count+=2;
		}
		else
			BINCOPY_FAIL("Unrecognized argument designated.");
	}

	if(Input_File==0)
		BINCOPY_FAIL("No input file specified.");

	if(Output_File==0)
		BINCOPY_FAIL("No output file specified.");

    /* Check the size of the input file to make sure that it is not empty */
    fseek(Input_File,0,SEEK_END);
    Input_Size=ftell(Input_File);
    fseek(Input_File,0,SEEK_SET);

	if(Input_Size==0)
		BINCOPY_FAIL("Input file is empty file.");

    /* Find the last position of the path */
	Name_Start=0;
    for(Count=0;Count<strlen(Output_Name);Count++)
    {
    	if((Output_Name[Count]=='\\')||(Output_Name[Count]=='/'))
    		Name_Start=Count+1;
    }

    /* Copy the section name and prepare for output */
    for(Count=0;Count<strlen(Output_Name)-Name_Start;Count++)
    {
        if((Output_Name[Count+Name_Start]!='.')&&(Output_Name[Count+Name_Start]!='\0'))
            Section_Name[Count]=Output_Name[Count+Name_Start];
        else
            break;
    }
    Section_Name[Count]='\0';
    if(Count==0)
		BINCOPY_FAIL("Invalid section name.");
        
    /* *.c output */
    Count=0;
	fprintf(Output_File,"/******************************************************************************\n");
	fprintf(Output_File,"Filename    : %s\n",&(Output_Name[Name_Start]));
	fprintf(Output_File,"Author      : bincopy image writer build %s-%s\n",__DATE__,__TIME__);
	fprintf(Output_File,"Date        : %s",ctime(&Raw_Time));
	fprintf(Output_File,"Description : The *.c code containing the array of the binary image.\n");
	fprintf(Output_File,"              Size of array: %d 8-bit words.\n",Input_Size);
	fprintf(Output_File,"              File generated by bincopy utility.\n");
	fprintf(Output_File,"              Copy the data and generate other kinds of files as needed.\n");
	fprintf(Output_File,"******************************************************************************/\n");
	fprintf(Output_File,"\n");
	fprintf(Output_File,"/* Begin Contents ************************************************************/\n");
    /* Print the array */
	fprintf(Output_File,"const unsigned char %s[%d]=\n",Section_Name,Input_Size);
	fprintf(Output_File,"{\n    ");
	while(1)
	{
        if(fread(&Temp,1,1,Input_File)!=1)
            break;

        /* See if we are printing the last one */
        if(Count==(Input_Size-1))
    		fprintf(Output_File,"0x%02X",Temp);
        else
        	fprintf(Output_File,"0x%02X, ",Temp);

		if(Count%16==15)
			fprintf(Output_File,"\n    ");

		Count++;
    }
    if(Count%16!=15)
		fprintf(Output_File,"\n");

	fprintf(Output_File,"};\n");

	fprintf(Output_File,"/* End Contents **************************************************************/\n");
	fprintf(Output_File,"\n");
	fprintf(Output_File,"/* End Of File ***************************************************************/\n");
	fprintf(Output_File,"\n");
	
	fclose(Input_File);
	fclose(Output_File);

	printf("Size of programming file: %d 8-bit words.\n",Input_Size);
	return 0;
}
/* End Function:main *********************************************************/

/* End Of File ***************************************************************/

/* Copyright (C) Evo-Devo Instrum. All rights reserved ***********************/

